﻿using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace Gmantis.Controls.DataGrid
{
    [StructLayout(LayoutKind.Sequential, Size = 1)]
    internal struct DoubleSumAggregator : IAggregator<double>
    {
        double IAggregator<double>.Zero()
        {
            return 0.0;
        }

        double IAggregator<double>.Sum(double left, double right)
        {
            return (left + right);
        }

        int IAggregator<double>.Compare(double x, double y)
        {
            return x.CompareTo(y);
        }
    }

    internal class DataGridColumnsVariableScrollStrategy : DataGridVariableScrollStrategy
    {
        // Fields
        public const double DefaultColumnWidth = 50.0;

        // Methods
        public DataGridColumnsVariableScrollStrategy(DataGridView view)
        {
            EventHandler<DataGridColumnEventArgs> handler = null;
            EventHandler<DataGridColumnEventArgs> handler2 = null;
            EventHandler<DataGridColumnEventArgs> handler3 = null;
            EventHandler handler4 = null;
            EventHandler<DataGridColumnEventArgs> handler5 = null;
            EventHandler handler6 = null;
            EventHandler<DataGridColumnEventArgs> handler7 = null;
            EventHandler<DataGridColumnEventArgs> handler8 = null;
            EventHandler<PropertyChangedEventArgs<int>> handler9 = null;
            this.View = view;
            if (handler == null)
            {
                handler = delegate(object s, DataGridColumnEventArgs e)
                {
                    int index = e.Column.DisplayIndex;
                    ViewColumn viewColumn = e.Column.ViewColumn;
                    if ((index >= 0) && (index < base.Table.Count))
                    {
                        base.Table.Update(index, (e.Column.IsFrozen || (e.Column.Visibility == Visibility.Collapsed)) ? 0.0 : viewColumn.RenderWidth);
                    }
                    base.RaiseOnChanged();
                };
            }
            this.View.ColumnActualWidthChanged += handler;
            if (handler2 == null)
            {
                handler2 = (s, e) => this.DestroyTable();
            }
            this.View.Model.Columns.AfterAddColumn += handler2;
            if (handler3 == null)
            {
                handler3 = (s, e) => this.DestroyTable();
            }
            this.View.Model.Columns.AfterRemoveColumn += handler3;
            if (handler4 == null)
            {
                handler4 = (s, e) => this.DestroyTable();
            }
            this.View.Model.ColumnsLoaded += handler4;
            if (handler5 == null)
            {
                handler5 = (s, e) => this.DestroyTable();
            }
            this.View.Model.Columns.ColumnVisibilityChanged += handler5;
            if (handler6 == null)
            {
                handler6 = (s, e) => this.DestroyTable();
            }
            this.View.Model.ColumnsLoaded += handler6;
            if (handler7 == null)
            {
                handler7 = (s, e) => this.DestroyTable();
            }
            this.View.Model.Columns.ColumnReordered += handler7;
            if (handler8 == null)
            {
                handler8 = (s, e) => this.DestroyTable();
            }
            this.View.Model.ColumnWidthChanged += handler8;
            if (handler9 == null)
            {
                handler9 = (s, e) => this.DestroyTable();
            }
            this.View.DataGrid.FrozenColumnCountChanged += handler9;
        }

        protected override AggregatingTable<double, DoubleSumAggregator> BuildTable()
        {
            DataGridColumn[] orderedColumns = this.View.Model.Columns.OrderedColumns;
            double[] lengths = new double[orderedColumns.Length];
            for (int i = 0; i < this.View.Model.Columns.OrderedColumns.Length; i++)
            {
                double renderWidth = 50.0;
                DataGridColumn column = orderedColumns[i];
                if (column.IsFrozen || (column.Visibility == Visibility.Collapsed))
                {
                    renderWidth = 0.0;
                }
                else
                {
                    DataGridLength width = column.GetWidth();
                    ViewColumn viewColumn = column.GetViewColumn(width.IsAbsolute);
                    if ((viewColumn != null) && viewColumn.HasRenderWidth)
                    {
                        renderWidth = viewColumn.RenderWidth;
                    }
                }
                lengths[i] = renderWidth;
            }
            return new AggregatingTable<double, DoubleSumAggregator>(lengths);
        }

        // Properties
        public DataGridView View { get; set; }
    }
}
